<script setup>
import { computed, ref, watch, nextTick } from "vue";
import Circle from "./Circle.vue";
import Cross from "./Cross.vue";
import XMake from "./XMake.vue";
import { ChessMove } from "../mcts/chessmove.js";
import { CONSTANTS } from "../mcts/CONSTANTS.js";
import { ChessState } from "../mcts/chessstate.js";
import { MCTSNode } from "../mcts/mctsnode.js";
import { MCTS } from "../mcts/mcts.js";
import BaseModal from "./BaseModal.vue";
const modelactive = ref(true);
const isgameovermodal = ref(false); // 判断是否游戏结束的那个modal，实际上该用插槽，但是我不会oao
const chessstate = ref(["你远不是隔壁老王的对手", CONSTANTS.CONTINUE]);
const isthinking = ref(false); // 是否在思考
let nxt_board = ref(
  Array.from({ length: CONSTANTS.SIZE * CONSTANTS.SIZE }, () => null)
); // 棋盘
let nxt_state = ref(new ChessState()); // mcts  状态

const close_modal = () => {
  modelactive.value = false;
  isgameovermodal.value = false;
};

watch(
  nxt_state,
  () => {
    if (nxt_state.value.game_result !== CONSTANTS.CONTINUE) {
      // 游戏结束了
      modelactive.value = !modelactive.value;
      isgameovermodal.value = true; // 区别开局modal
      if (nxt_state.value.game_result === CONSTANTS.X) {
        chessstate.value = ["你输了！", CONSTANTS.X];
      } else if (nxt_state.value.game_result === CONSTANTS.O) {
        chessstate.value = ["你赢了！找隔壁老王领奖", CONSTANTS.O];
      } else if (nxt_state.value.game_result === CONSTANTS.DRAW) {
        chessstate.value = ["平局！", CONSTANTS.DRAW];
      }
    } else {
      // 游戏继续
      if (nxt_state.value.to_move !== CONSTANTS.O) {
        chessstate.value = ["X's turn", CONSTANTS.CONTINUE];
      } else {
        chessstate.value = ["O's turn", CONSTANTS.CONTINUE];
      }
    }
  },
  { deep: true }
);

const AI_PLAY = () => {
  nxt_state.value = new ChessState(nxt_board.value, CONSTANTS.X); // 初始x先走
  let node = new MCTSNode(nxt_state.value, null);
  let mcts = new MCTS(node);
  let best_node = mcts.best_action(CONSTANTS.TRY_NUMBER); // 耗时
  nxt_state.value = best_node.state;
  nxt_board.value = nxt_state.value.board;
};

const AI_PLAY_settimeout = () => {
  isthinking.value = true; // 为什么遮罩等到ai_play之后才执行呢？
  setTimeout(() => {
    AI_PLAY();
    isthinking.value = false; // 如果这句运行，遮罩一直不会出现，为什么？？
  }, 50);
};

const person_play = (i) => {
  let move = new ChessMove(i, CONSTANTS.O);
  if (!nxt_state.value.is_move_legal(move)) {
    console.log("人工下棋失败");

    return false;
  }
  nxt_state.value = nxt_state.value.chessmove(move);
  nxt_board.value = nxt_state.value.board;
  return true;
};

const aifirst = () => {
  isgameovermodal.value = false; // 关闭结果框
  nxt_board.value = Array.from(
    { length: CONSTANTS.SIZE * CONSTANTS.SIZE },
    () => null
  );

  nxt_state.value = new ChessState();
  close_modal(); // 本来这一步modal应该关闭了的，但是不知道为什么要等到下面AI_PLAY()执行完成之后才能关闭，加个50的延迟勉强解决
  isthinking.value = true; // 为什么遮罩等到ai_play之后才执行呢？
  AI_PLAY_settimeout();
};

const playerfirst = () => {
  isgameovermodal.value = false; // 关闭结果框
  // 初始化
  nxt_board.value = Array.from(
    { length: CONSTANTS.SIZE * CONSTANTS.SIZE },
    () => null
  );

  nxt_state.value = new ChessState(nxt_board.value, CONSTANTS.O); // 需要指定tomove为 - 1;
  close_modal();
};

const handleClick = (i) => {
  // 玩家move需要合法，并且游戏没有结束，电脑才能接着下棋
  if (person_play(i) && nxt_state.value.game_result === CONSTANTS.CONTINUE) {
    // 本来这一步person_play执行后应该马上渲染棋子的，但是不知道为什么要等到下面AI_PLAY()执行完成之后才和ai下棋一起渲染出来，加个50的延迟勉强解决
    AI_PLAY_settimeout();
  }
};
const has_border_right = (i) => {
  return [0, 1, 3, 4, 6, 7].includes(i); // 3*3
  // return [
  //   0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23,
  // ].includes(i); // 5 * 5
};
const has_border_bottom = (i) => {
  return [0, 1, 2, 3, 4, 5].includes(i); // 3*3
  // return [
  //   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  // ].includes(i); // 5 * 5
};

const gridClasses = computed(() => {
  return [`grid-cols-${CONSTANTS.SIZE}`, `grid-rows-${CONSTANTS.SIZE}`];
});
</script>
<template>
  <div class="">
    <div
      class="mx-auto text-center font-bold text-xl mb-2 p-1"
      :class="
        chessstate[1] !== CONSTANTS.CONTINUE ? 'text-rose-400' : 'text-teal-500'
      "
    >
      {{ chessstate[0] }}- {{ isthinking }}
    </div>
    <div
      class="border m-2 mb-20 grid justify-items-center content-center place-content-center place-items-center grid-cols-3 grid-rows-3 relative"
      :class="gridClasses"
    >
      <!-- 使用tailwindcss  这里:class="[`grid-cols-${CONSTANTS.SIZE.toString()}`,`grid-rows-${CONSTANTS.SIZE.toString()}`,]"不起效，不知道为啥 -->
      <div
        v-for="(_, i) in CONSTANTS.SIZE * CONSTANTS.SIZE"
        :key="'cell-' + i"
        class="cell"
        :class="{
          'border-r': has_border_right(i),
          'border-b': has_border_bottom(i),
        }"
        @click="handleClick(i)"
      >
        <Transition name="modal-inner">
          <Circle v-if="nxt_board[i] === CONSTANTS.O" />
        </Transition>
        <Transition name="modal-inner">
          <!-- <Cross v-if="nxt_board[i] === CONSTANTS.X" /> -->
          <XMake v-if="nxt_board[i] === CONSTANTS.X" class="text-slate-600" />
        </Transition>
      </div>
      <Transition name="modal-inner2">
        <div
          class="absolute z-20 top-0 left-0 h-full w-full bg-slate-800 bg-opacity-30 flex justify-center items-center"
          v-show="isthinking"
        >
          <div class="text-white text-2xl">等下，老王正在思考......</div>
        </div>
      </Transition>
    </div>
    <BaseModal
      :modelactive="modelactive"
      @ai-first="aifirst"
      @player-first="playerfirst"
    >
      <div class="text-slate-800">
        <div v-if="!isgameovermodal">
          <h2 class="text-xl font-semibold my-2">“井”字棋游戏说明</h2>
          <p class="tracking-wide leading-relaxed text-slate-600">
            井字棋，英文名叫Tic-Tac-Toe，是一种在3*3格子上进行的连珠游戏，由于棋盘一般不画边框，格线排成“井”字故得名。由分别代表O和X的两个游戏者轮流在格子里留下标记（一般来说先手者为X），任意三个标记形成一条直线，则为获胜。
          </p>
          <p class="text-rose-400">
            赢我每一局，可截图找隔壁老王领100块钱，门票只要1毛钱
          </p>
        </div>
        <div v-else class="">
          <h2 class="text-xl my-2 font-medium">{{ chessstate[0] }}</h2>
        </div>
      </div>
    </BaseModal>
  </div>
</template>
<style scoped>
.modal-inner-enter-active {
  transition: all 0.3s cubic-bezier(0.52, 0.02, 0.19, 1.02) 0.15s;
}
.modal-inner-leave-active {
  transition: all 0.3s cubic-bezier(0.52, 0.02, 0.19, 1.02);
}

.modal-inner-enter-from {
  opacity: 0;
  transform: scale(0.8);
}
.modal-inner-leave-to {
  opacity: 0;
  transform: scale(0.8);
}

.modal-inner2-enter-active {
  transition: all 0.3s cubic-bezier(0.52, 0.02, 0.19, 1.02) 0.55s;
}
.modal-inner2-leave-active {
  transition: all 0.3s cubic-bezier(0.52, 0.02, 0.19, 1.02);
}

.modal-inner2-enter-from {
  opacity: 0;
  transform: scale(0.8);
}
.modal-inner2-leave-to {
  opacity: 0;
  transform: scale(0.8);
}
</style>
